package setup

import (
	"fmt"
	"gopkg.in/natefinch/lumberjack.v2"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"io"
	"log"
	"my-gin-tiktok/app/models"
	"my-gin-tiktok/global"
	"os"
	"time"
)

func InitDatabase() *gorm.DB {
	switch global.App.Config.Database.Driver {
	case "mysql":
		return InitMySQL()
	default:
		return InitMySQL()
	}
}

func GetGormLogWriter() logger.Writer {
	var writer io.Writer

	if global.App.Config.Database.EnableFileLogWriter {
		writer = &lumberjack.Logger{
			Filename:   global.App.Config.Log.RootDir + "/" + global.App.Config.Database.LogFilename,
			MaxSize:    global.App.Config.Log.MaxSize,
			MaxBackups: global.App.Config.Log.MaxBackups,
			MaxAge:     global.App.Config.Log.MaxAge,
			Compress:   global.App.Config.Log.Compress,
		}
	} else {
		writer = os.Stdout
	}
	return log.New(writer, "\r\n", log.LstdFlags)
}

func GetGormLogger() logger.Interface {
	var logMode logger.LogLevel
	switch global.App.Config.Database.LogMode {
	case "silent":
		logMode = logger.Silent
	case "error":
		logMode = logger.Error
	case "warn":
		logMode = logger.Warn
	case "info":
		logMode = logger.Info
	default:
		logMode = logger.Info
	}

	writer := GetGormLogWriter()
	return logger.New(writer, logger.Config{
		SlowThreshold:             200 * time.Millisecond,                          // 慢 SQL 阈值
		LogLevel:                  logMode,                                         // 日志级别
		IgnoreRecordNotFoundError: false,                                           // 忽略ErrRecordNotFound（记录未找到）错误
		Colorful:                  !global.App.Config.Database.EnableFileLogWriter, // 禁用彩色打印
	})
}

func InitMySQL() *gorm.DB {
	dbConfig := global.App.Config.Database
	if dbConfig.Database == "" {
		fmt.Println("InitMySQL Failed: Config.Database is empty")
		return nil
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", dbConfig.UserName,
		dbConfig.Password, dbConfig.Host, dbConfig.Port, dbConfig.Database)
	sqlConfig := mysql.Config{
		DSN:                       dsn,
		DefaultStringSize:         200,
		DisableDatetimePrecision:  true,
		DontSupportRenameIndex:    true,
		DontSupportRenameColumn:   true,
		SkipInitializeWithVersion: false,
	}

	gormLogger := GetGormLogger()
	db, err := gorm.Open(mysql.New(sqlConfig), &gorm.Config{Logger: gormLogger})

	if err != nil {
		fmt.Println("InitMySQL Failed:", err)
		return nil
	}

	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConns)
	sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConns)
	InitTables(db)
	return db
}

func InitTables(db *gorm.DB) {
	err := db.AutoMigrate(models.User{})
	if err != nil {
		panic("migrate table failed:" + err.Error())
	}
}
